home *** CD-ROM | disk | FTP | other *** search
/ Cream of the Crop 22 / Cream of the Crop 22.iso / os2 / ext2_200.zip / EXT2_SRC.ZIP / 32BITS / EXT2-OS2 / FSD32 / FS32_MOU.C < prev    next >
C/C++ Source or Header  |  1996-09-21  |  15KB  |  381 lines

  1. //
  2. // $Header: D:/32bits/ext2-os2/fsd32/RCS/fs32_mount.c,v 1.1 1996/09/21 22:25:25 Willm Exp Willm $
  3. //
  4.  
  5. // 32 bits Linux ext2 file system driver for OS/2 WARP - Allows OS/2 to
  6. // access your Linux ext2fs partitions as normal drive letters.
  7. // Copyright (C) 1995, 1996 Matthieu WILLM
  8. //
  9. // This program is free software; you can redistribute it and/or modify
  10. // it under the terms of the GNU General Public License as published by
  11. // the Free Software Foundation; either version 2 of the License, or
  12. // (at your option) any later version.
  13. //
  14. // This program is distributed in the hope that it will be useful,
  15. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  16. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  17. // GNU General Public License for more details.
  18. //
  19. // You should have received a copy of the GNU General Public License
  20. // along with this program; if not, write to the Free Software
  21. // Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  22. #ifdef __IBMC__
  23. #pragma strings(readonly)
  24. #endif
  25.  
  26. #define INCL_DOS
  27. #define INCL_DOSERRORS
  28. #define INCL_NOPMAPI
  29. #include <os2.h>
  30.  
  31. #include <string.h>
  32.  
  33. #include <os2/types.h>
  34. #include <os2/StackToFlat.h>
  35. #include <linux/fs.h>
  36. #include <os2/os2proto.h>
  37. #include <os2/fsd32.h>
  38. #include <os2/fsh32.h>
  39. #include <os2/DevHlp32.h>
  40. #include <os2/log.h>
  41. #include <os2/trace.h>
  42. #include <os2/errors.h>
  43. #include <os2/files.h>
  44. #include <os2/volume.h>
  45. #include <linux/fs_proto.h>
  46. #include <linux/ext2_proto.h>
  47. #include <linux/stat.h>
  48. #include <os2/vfsapi.h>
  49. #include <os2/ifsdbg.h>
  50.  
  51. #define ERROR_VOLUME_NOT_MOUNTED 0xEE00                // IFS specific
  52.  
  53. extern char Use_Extended_Interface;
  54. extern struct file_system_type ext2_fs_type;
  55.  
  56. struct super_block * do_mount(
  57.                               struct vpfsi32          *pvpfsi,
  58.                               union  vpfsd32          *pvpfsd, 
  59.                               unsigned short           hVPB, 
  60.                   struct file_system_type *type
  61.                              ) {
  62.     struct super_block *tmp;
  63.     struct super_block *sb;
  64.     int                 rc;
  65.  
  66.  
  67.     sb = get_empty_super();
  68.     pvpfsd->u.sb = sb;
  69.  
  70.     if ((sb) && (sb->s_magic_internal == SUPER_MAGIC)) {
  71.         sb->sector_size       = pvpfsi->vpi_bsize;
  72.         sb->nb_sectors        = pvpfsi->vpi_totsec;
  73.         sb->s_drive           = pvpfsi->vpi_drive;
  74.         sb->s_unit            = pvpfsi->vpi_unit;
  75.         sb->s_blocksize       = BLOCK_SIZE;
  76.         sb->sectors_per_block = BLOCK_SIZE / sb->sector_size;
  77.         sb->s_dev             = hVPB;
  78.     sb->s_status          = VOL_STATUS_MOUNT_IN_PROGRESS;
  79.         if (!Read_Write)
  80.             sb->s_flags       = MS_RDONLY;
  81.  
  82.     /*
  83.      * Strategy 2 I/O support processing
  84.      */
  85.     if (Use_Extended_Interface) {
  86.     struct DriverCaps32 *pDCS;
  87.     struct VolChars32   *pVCS;
  88.  
  89.     if (pvpfsi->vpi_pDCS.seg) {
  90.         if ((rc = DevHlp32_VirtToLin(pvpfsi->vpi_pDCS, __StackToFlat(&pDCS))) == NO_ERROR) {
  91.             if (pvpfsi->vpi_pVCS.seg) {
  92.                 if ((rc = DevHlp32_VirtToLin(pvpfsi->vpi_pVCS, __StackToFlat(&pVCS))) == NO_ERROR) {
  93.  
  94.                         if ((pDCS) && (pDCS->Strategy2.seg)) {
  95.                             kernel_printf("\tStrategy 2 entry point found");
  96.                             if (pVCS) {
  97.                                 kernel_printf("\tVolume descriptor        : 0x%04X", pVCS->VolDescriptor);           /* see equates below                    */
  98.                                 kernel_printf("\tAverage seek time        : %d",     pVCS->AvgSeekTime);             /* milliseconds, if unknown, FFFFh      */
  99.                                 kernel_printf("\tAverage latency time     : %d",     pVCS->AvgLatency);               /* milliseconds, if unknown, FFFFh      */
  100.                                 kernel_printf("\tBlocks on smallest track : %d",     pVCS->TrackMinBlocks);          /* blocks on smallest track             */
  101.                                 kernel_printf("\tBlocks on largest track  : %d",     pVCS->TrackMaxBlocks);          /* blocks on largest track              */
  102.                                 kernel_printf("\tMax scatter-gather list  : %d",     pVCS->MaxSGList);               /* Adapter scatter/gather list limit    */
  103.                             }
  104.                             if ((pVCS) && (pVCS->VolDescriptor & VC_REMOVABLE_MEDIA)) {
  105.                                 kernel_printf("\tMedia is removable, not supported for strat 2 yet !");
  106.                             } else {
  107.                                 kernel_printf("\tMedia is NOT removable, using strat 2 I/Os");
  108.                                 sb->s_strat2.seg = pDCS->Strategy2.seg;
  109.                                 sb->s_strat2.ofs = pDCS->Strategy2.ofs;
  110.                 }
  111.                         } else {
  112.                             kernel_printf("\tNO strategy 2 entry point found, using standard FSH_DOVOLIO instead");
  113.                         }
  114.                     } else {
  115.                         kernel_printf("\tError while thunking pvpfsi->vpi_pVCS - rc = %d", rc);
  116.                     }
  117.                 }
  118.             } else {
  119.                 kernel_printf("\tError while thunking pvpfsi->vpi_pDCS - rc = %d", rc);
  120.             }
  121.         }
  122.     } else {
  123.         kernel_printf("\tUsing standard I/Os as requested on the IFS command line.");
  124.     }
  125.  
  126.     if ((type) && (type->read_super)) {
  127.         tmp = type->read_super(sb, 0, 0);
  128.         if (tmp) {
  129.         sb->s_blocks_per_page = (unsigned char)(4096 / sb->s_blocksize);
  130.             sb->s_status          = VOL_STATUS_MOUNTED;
  131.         /*
  132.          * nothing else to do ...
  133.          */
  134.     } else {
  135.             put_super(sb);
  136.         sb = 0;
  137.         }
  138.     } else {
  139.         sb = 0;
  140.     }
  141.  
  142.     } else {
  143.         sb = 0;
  144.     }
  145.  
  146.     return sb;
  147. }
  148.  
  149. /*
  150.  * Alters the mount flags of a mounted file system. Only the mount point
  151.  * is used as a reference - file system type and the device are ignored.
  152.  * FS-specific mount options can't be altered by remounting.
  153.  */
  154.  
  155. int do_remount_sb(struct super_block *sb, int flags, char *data)
  156. {
  157.     int retval;
  158. #ifndef OS2    
  159.     if (!(flags & MS_RDONLY ) && sb->s_dev && is_read_only(sb->s_dev))
  160.         return -EACCES;
  161.         /*flags |= MS_RDONLY;*/
  162.     /* If we are remounting RDONLY, make sure there are no rw files open */
  163.     if ((flags & MS_RDONLY) && !(sb->s_flags & MS_RDONLY))
  164.         if (!fs_may_remount_ro(sb->s_dev))
  165.             return -EBUSY;
  166. #endif
  167.     if (sb->s_op && sb->s_op->remount_fs) {
  168.         retval = sb->s_op->remount_fs(sb, __StackToFlat(&flags), data);
  169.         if (retval)
  170.             return retval;
  171.     }
  172.     sb->s_flags = (sb->s_flags & ~MS_RMT_MASK) |
  173.         (flags & MS_RMT_MASK);
  174.     return 0;
  175. }
  176.  
  177. int do_unmount(struct super_block *sb) {
  178.  
  179.     if (!fs_may_umount(sb->s_dev, sb->s_mounted)) {
  180.         kernel_printf("\tdo_unmount WARNING !! device busy");
  181.         return ERROR_DEVICE_IN_USE;
  182.     }
  183.     invalidate_files(sb, 1);
  184.     sync_buffers(sb->s_dev, 1);
  185.     iput(sb->s_mounted);
  186.     sync_inodes(sb->s_dev);
  187.     sync_buffers(sb->s_dev, 1);
  188.     if (!sb->s_is_swapper_device) {
  189.         invalidate_inodes(sb->s_dev);
  190.         sync_buffers(sb->s_dev, 1);
  191.     }
  192.     if ((sb->s_op) && (sb->s_op->put_super))
  193.         sb->s_op->put_super(sb);
  194.         sync_buffers(sb->s_dev, 1);
  195.     if (!sb->s_is_swapper_device) {
  196.         invalidate_buffers(sb->s_dev);
  197.     }
  198.     put_super(sb);
  199.  
  200.     sync_buffers(0, 1);
  201.     sync_buffers(0, 1);
  202.  
  203.     return NO_ERROR;
  204. }
  205.  
  206. extern int check_ext2fs_magic(struct vpfsi32 *pvpfsi, unsigned short hVPB);
  207.  
  208. /*
  209.  * struct fs32_mount_parms {
  210.  *     PTR16          pBoot;
  211.  *     unsigned short hVPB;
  212.  *     PTR16          pvpfsd;
  213.  *     PTR16          pvpfsi;
  214.  *     unsigned short flag;
  215.  * };
  216.  */
  217. int FS32ENTRY fs32_mount(struct fs32_mount_parms *parms) {
  218.     struct vpfsi32 *pvpfsi;
  219.     union  vpfsd32 *pvpfsd;
  220.     char           *pBoot;
  221.     int             rc;
  222.     int i;
  223.     struct super_block *sb;
  224.     struct super_block *old_sb;
  225.     unsigned short oldhVPB;
  226.  
  227.  
  228.     parms = __StackToFlat(parms);
  229.  
  230.     if ((rc = DevHlp32_VirtToLin(parms->pvpfsi, __StackToFlat(&pvpfsi))) == NO_ERROR) {
  231.         if ((rc = DevHlp32_VirtToLin(parms->pvpfsd, __StackToFlat(&pvpfsd))) == NO_ERROR) {
  232.  
  233.     switch(parms->flag) {
  234.         case MOUNT_MOUNT :
  235.              kernel_printf("FS_MOUNT flg = MOUNT_MOUNT hVPB = 0x%04X", parms->hVPB);
  236.  
  237.             if ((rc = DevHlp32_VirtToLin(parms->pBoot, __StackToFlat(&pBoot))) == NO_ERROR) {
  238.                 /*
  239.                  * We zero out pvpfsd for safety purposes !
  240.                  */
  241.                 memset(pvpfsd, 0, sizeof(union vpfsd32));
  242.  
  243.         if ((rc = check_ext2fs_magic(pvpfsi, parms->hVPB)) == NO_ERROR) {
  244.                     /*
  245.                      * The volume serial number is a CRC checksum of the boot sector
  246.                      */
  247.                     pvpfsi->vpi_vid = updcrc((unsigned char *)pBoot, pvpfsi->vpi_bsize);
  248.  
  249.                     /*
  250.                      * The volume label is dummy for the moment ("ext2fs_<drive>")
  251.                      */
  252.                     sprintf(pvpfsi->vpi_text, "EXT2FS_%c", pvpfsi->vpi_unit + 'A');
  253.  
  254.  
  255.                     /*
  256.                      * Is there another instance of the drive ?
  257.                      *     - Yes : update internal volume table and return silently
  258.                      *     - No  : continue the mount process
  259.                      */
  260.                     if ((rc = fsh32_findduphvpb(parms->hVPB, __StackToFlat(&oldhVPB))) == NO_ERROR) {
  261.                         kernel_printf(" \tFSH_FINDDUPHVPB(0x%0X) - Found dup hVPB 0x%0X", (int)parms->hVPB, (int)oldhVPB);
  262.  
  263.                 old_sb = getvolume(oldhVPB);
  264.  
  265.                         if ((old_sb) && (old_sb->s_magic_internal == SUPER_MAGIC)) {
  266.                             old_sb->s_status = VOL_STATUS_MOUNTED;
  267.                             rc               = NO_ERROR;
  268.                         } else {
  269.                             kernel_printf("Cannot find old superblock !");
  270.                             rc = ERROR_INVALID_PARAMETER;
  271.                         }
  272.  
  273.  
  274.                     } else {
  275.                         kernel_printf(" \tFSH_FINDDUPHVPB - NO dup hVPB");
  276.                         /*
  277.                          * This is the first instance of the drive
  278.                          */
  279.  
  280.                         sb = do_mount(pvpfsi, pvpfsd, parms->hVPB, &ext2_fs_type);
  281.  
  282.                         if (sb) {
  283.  
  284.                             kernel_printf("Volume characteristics :");
  285.                             kernel_printf("========================");
  286.                         kernel_printf("\t volume id    : 0x%08X", pvpfsi->vpi_vid);
  287.                         kernel_printf("\t hDEV         : 0x%08X", pvpfsi->vpi_hDEV);
  288.                         kernel_printf("\t sector size  : %u", pvpfsi->vpi_bsize);
  289.                         kernel_printf("\t sector/track : %u", pvpfsi->vpi_trksec);
  290.                         kernel_printf("\t heads        : %u", pvpfsi->vpi_nhead);
  291.                         kernel_printf("\t tot sectors  : %lu", pvpfsi->vpi_totsec);
  292.                         kernel_printf("\t drive (0=A)  : %d", (int)(pvpfsi->vpi_drive));
  293.                         kernel_printf("\t unit code    : %d", (int)(pvpfsi->vpi_unit));
  294.                         kernel_printf("\t volume label : %s", pvpfsi->vpi_text);
  295.                         kernel_printf("\t hVPB         : 0x%08X", parms->hVPB);
  296.  
  297.                          sb->s_status = VOL_STATUS_MOUNTED;
  298.                             pvpfsd->u.sb = sb;
  299.                             rc = NO_ERROR;
  300.                         } else {
  301.                             rc = ERROR_VOLUME_NOT_MOUNTED;
  302.                         }
  303.                     }
  304.  
  305.  
  306.                 } else {
  307.                     kernel_printf("\tbasic superblock validation failed for volume 0x%04X", (int)parms->hVPB);
  308.                     rc = ERROR_VOLUME_NOT_MOUNTED;
  309.                 }
  310.             } else {
  311.                 kernel_printf("FS_MOUNT - couldn't thunk pBoot");
  312.             }
  313.         break;
  314.  
  315.  
  316.     case MOUNT_VOL_REMOVED :
  317.             kernel_printf("FS_MOUNT flg = MOUNT_VOL_REMOVED hVPB = 0x%04X", parms->hVPB);
  318.             if ((pvpfsd->u.sb) && (pvpfsd->u.sb->s_magic_internal == SUPER_MAGIC)) {
  319.                 pvpfsd->u.sb->s_status = VOL_STATUS_REMOVED;
  320.                 rc                     = NO_ERROR;
  321.             } else {
  322.                 rc                     = ERROR_INVALID_PARAMETER;
  323.             }
  324.         break;
  325.  
  326.     case MOUNT_RELEASE :
  327.              kernel_printf("FS_MOUNT flg = MOUNT_RELEASE hVPB = 0x%04X", parms->hVPB);
  328.              if ((pvpfsd->u.sb) && (pvpfsd->u.sb->s_magic_internal == SUPER_MAGIC)) {
  329.                  kernel_printf("\tvalid superblock present in VPB");
  330.  
  331.                     switch(pvpfsd->u.sb->s_status) {
  332.                         case VOL_STATUS_REMOVED:
  333.                 kernel_printf("\tmedia is NOT present");
  334.                             /*
  335.                              * This is a "hard" unmount !!
  336.                              */
  337.                             invalidate_files(pvpfsd->u.sb, 0);
  338.                             hard_invalidate_inodes(pvpfsd->u.sb->s_dev);
  339.                             if ((pvpfsd->u.sb->s_op) && (pvpfsd->u.sb->s_op->put_super))
  340.                             pvpfsd->u.sb->s_op->put_super(pvpfsd->u.sb);
  341.                             invalidate_buffers(pvpfsd->u.sb->s_dev);
  342.                             put_super(pvpfsd->u.sb);
  343.                             memset(pvpfsd, 0, sizeof(union vpfsd32));
  344.                             rc = NO_ERROR;
  345.                             break;
  346.  
  347.                         case VOL_STATUS_MOUNTED:
  348.                 kernel_printf("\tmedia is present");
  349.                             rc = do_unmount(pvpfsd->u.sb);
  350.                             memset(pvpfsd, 0, sizeof(union vpfsd32));
  351.                             break;
  352.  
  353.                         default:
  354.                             kernel_printf("FS_MOUNT - unexpected volume status");
  355.                             rc = ERROR_INVALID_PARAMETER;
  356.                             break;
  357.                     }
  358.                 } else {
  359.                     kernel_printf("\tNO superblock present in VPB (probably unmounting a dup VPB)");
  360.             rc = NO_ERROR;
  361.                 }
  362.         break;
  363.  
  364.  
  365.             case MOUNT_ACCEPT :
  366.                 kernel_printf("FS_MOUNT flg = MOUNT_ACCEPT hVPB = 0x%04X", parms->hVPB);
  367. //                rc = ERROR_NOT_SUPPORTED;
  368.                 rc = NO_ERROR;
  369.                 break;
  370.  
  371.             default :
  372.                 kernel_printf("FS_MOUNT() invalid flag %d", parms->flag);
  373.                 rc = ERROR_INVALID_PARAMETER;
  374.                 break;
  375.         }
  376.  
  377.         }
  378.     }
  379.     return rc;
  380. }
  381.